package com.guit.hrms.service.impl;

import  com.guit.hrms.dto.recuitmentDTO.*;
import com.guit.hrms.mapper.AcademyMapper;
import com.guit.hrms.mapper.DepartmentMapper;
import com.guit.hrms.mapper.FileRepository;
import com.guit.hrms.mapper.RecruitmentMapper;
import com.guit.hrms.po.academy.Academy;
import com.guit.hrms.po.department.Department;
import com.guit.hrms.po.position.Position;
import com.guit.hrms.po.recruitmentPO.FileEntity;
import com.guit.hrms.po.recruitmentPO.PlanDeptJob;
import com.guit.hrms.po.recruitmentPO.Recruitment;
import com.guit.hrms.service.RecruitmentService;
import com.guit.hrms.strings.VerifyRS;
import com.guit.hrms.utils.ThreadLocalUtil;
import com.guit.hrms.vo.department.DepartmentVO;
import com.guit.hrms.vo.recruitmentVO.ALOfEDNVO;
import com.guit.hrms.vo.recruitmentVO.PlanDeptJobVO;
import com.guit.hrms.vo.recruitmentVO.RecruitmentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

;

@Service
@Slf4j
public class RecruitmentServiceImpl implements RecruitmentService {
    @Autowired
    RecruitmentMapper recruitmentMapper;
    @Autowired
    private FileRepository fileRepository;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private AcademyMapper academyMapper;

    /**
     * 新增招聘公告
     * @param r 招聘公告信息
     */
    @Transactional(rollbackFor = Exception.class) //事务管理
    @Override
    public void newRecruitment(RecruitmentDTO r) {
        System.out.println("新建招聘计划-------------------------------");
        System.out.println(r.getDepts());
        System.out.println(r.getRecruiterId());
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        //构造recruitment_plan表
        Recruitment recruitment = Recruitment.builder()
                .planName(r.getPlanName())
                .planCode(r.getPlanCode())
                .planType(r.getPlanType())
                .recruiterId(r.getRecruiterId())
                .recruiterName(r.getRecruiterName())
                .recruiterPhone(r.getRecruiterPhone())
                .recruitmentConditions(r.getRecruitmentConditions())
                .benefitsDescription(r.getBenefitsDescription())
                .startDate(r.getStartDate())
                .endDate(r.getEndDate())
                .publishDate(r.getPublishDate())
                .interviewProcess(r.getInterviewProcess())
                .approveStatus(r.getApproveStatus())
                .approverId(r.getApproverId())
                .notes(r.getNotes())
                .attachments(null)
                .createdBy(username)
                .updatedBy(username)
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
//                .content(r.getContent())
                .build();
        if (r.getPlanType() == 3) {
            recruitment.setContent(r.getContent());
            recruitmentMapper.newRecruitment(recruitment);
            return;
        }

        recruitmentMapper.newRecruitment(recruitment);
        Integer planId = recruitment.getPlanId();



        //构造部门/二级学院表
        //从r中提取depts
        List<ALOfEDNDTO> depts = r.getDepts();
        for (ALOfEDNDTO dept : depts) {
            List<PlanDeptJobDTO> positions = dept.getPositions();
            for (PlanDeptJobDTO position : positions) {
                PlanDeptJob planDeptJob = PlanDeptJob.builder()
                        .planId(planId)
                        .numbering(dept.getNumbering())
                        .positionNumber(position.getPositionNumber())
                        .positionName(position.getPositionName())
                        .positionProperties(position.getPositionProperties())
                        .jobDescription(position.getJobDescription())
                        .jobRequired(position.getJobRequired())
                        .person(position.getPerson())
                        .professionalSkillsRight(position.getProfessionalSkillsRight())
                        .communicationSkillsRight(position.getCommunicationSkillsRight())
                        .teamworkAbilityRight(position.getTeamworkAbilityRight())
                        .build();
                if (r.getPlanType() == 1) {
                    recruitmentMapper.newPlanDeptJob(planDeptJob);
                } else if (r.getPlanType() == 2) {
                    recruitmentMapper.newPlanAcademyJob(planDeptJob);
                }

            }
        }


    }

    /**
     * 上传附件到招聘计划
     */
    @Override
    @Transactional
    public Integer addFileToRecruitmentPlan(Integer planId, MultipartFile file, String fileName) {
        // 1. 获取现有记录
        FileEntity fileEntity = fileRepository.findById(Long.valueOf(planId))
                .orElseThrow(() -> new RuntimeException("招聘计划不存在: " + planId));
        
        try {
            // 2. 更新文件信息
            fileEntity.setAttachments(file.getBytes());
            fileEntity.setFileName(fileName);  // 使用原始文件名
            fileEntity.setContentType(file.getContentType());
            fileEntity.setUpdatedAt(LocalDateTime.now());
            
            // 3. 保存更新
            return recruitmentMapper.updateAttachment(fileEntity);
        } catch (IOException e) {
            throw new RuntimeException("文件处理失败", e);
        }
    }

    /**
     * 获取招聘公告
     * @return
     */
    @Override
    public List<RecruitmentVO> queryRecruitment() {
        // 1. 获取基本招聘计划列表
        List<RecruitmentVO> recruitmentVOList = recruitmentMapper.queryRecruitmentPlan();
        
        // 2. 遍历每个招聘计划
        for (RecruitmentVO recruitmentVO : recruitmentVOList) {
            Integer planId = recruitmentVO.getPlanId();
            List<ALOfEDNVO> depts = new ArrayList<>();
            String name = null;
            // 根据计划类型选择不同的查询方式
            if (recruitmentVO.getPlanType() == 1) {
                // 行政岗位 - 查询 plan_dept_job 表
                List<String> deptIds = recruitmentMapper.getDeptIdByPlanId(planId);
                for (String deptId : deptIds) {
                    name = departmentMapper.getDepartmentByDeptNumber(deptId).getDeptName();
                    List<String> positionNames = recruitmentMapper
                        .getPositionNameByPlanIdAndDeptId(planId, deptId);
                    List<PlanDeptJobVO> planDeptJobVOList = new ArrayList<>();
                    for (String positionName : positionNames) {
                        PlanDeptJobVO planDeptJobVO = recruitmentMapper
                            .getByAllPrimaryKey(planId, deptId, positionName);
                        planDeptJobVOList.add(planDeptJobVO);
                    }
                    
                    ALOfEDNVO dept = new ALOfEDNVO(deptId, name,planDeptJobVOList);
                    depts.add(dept);
                }
            } else if (recruitmentVO.getPlanType() == 2) {
                // 专任教师 - 查询 plan_academy_job 表
                List<String> academyIds = recruitmentMapper.getAcademyIdByPlanId(planId);
                for (String academyId : academyIds) {
                    name = academyMapper.getAcademyByDeptNumber(academyId).getAcademyName();
                    List<String> positionNames = recruitmentMapper
                        .getPositionNameByPlanIdAndAcademyId(planId, academyId);
                    List<PlanDeptJobVO> planDeptJobVOList = new ArrayList<>();
                    
                    for (String positionName : positionNames) {
                        PlanDeptJobVO planDeptJobVO = recruitmentMapper
                            .getByAllPrimaryKeyFromAcademy(planId, academyId, positionName);
                        planDeptJobVOList.add(planDeptJobVO);
                    }
                    
                    ALOfEDNVO dept = new ALOfEDNVO(academyId, name, planDeptJobVOList);
                    depts.add(dept);
                }
            }
            // planType == 3 的情况不需要处理部门信息
            
            recruitmentVO.setDepts(depts);
        }
        
        // 遍历每个招聘计划输出日志
        for (RecruitmentVO plan : recruitmentVOList) {
            logRecruitmentPlan(plan);
        }
        return recruitmentVOList;
    }

    //格式化日志(所有招聘计划)
    private void logRecruitmentPlan(RecruitmentVO plan) {
        StringBuilder sb = new StringBuilder();
        sb.append("\n==================== 招聘计划详情 ====================\n");
        sb.append(String.format("基本信息:\n  ID: %d\n  名称: %s\n  编号: %s\n  类型: %d\n", 
            plan.getPlanId(), plan.getPlanName(), plan.getPlanCode(), plan.getPlanType()));
        
        if (!plan.getDepts().isEmpty()) {
            sb.append("\n部门信息:");
            for (ALOfEDNVO dept : plan.getDepts()) {
                sb.append(String.format("\n  部门编号: %s", dept.getNumbering()));
                if (!dept.getPositions().isEmpty()) {
                    sb.append("\n  职位列表:");
                    for (PlanDeptJobVO pos : dept.getPositions()) {
                        sb.append(String.format("\n    - %s (%s)", 
                            pos.getPositionName(), pos.getPositionNumber()));
                        sb.append(String.format("\n      描述: %s", pos.getJobDescription()));
                        sb.append(String.format("\n      要求: %s", pos.getJobRequired()));
                        sb.append(String.format("\n      人数: %d", pos.getPerson()));
                    }
                }
            }
        }
        
        sb.append("\n\n招聘信息:");
        sb.append(String.format("\n  招聘人: %s", plan.getRecruiterName()));
        sb.append(String.format("\n  联系电话: %s", plan.getRecruiterPhone()));
        sb.append(String.format("\n  招聘条件: %s", plan.getRecruitmentConditions()));
        sb.append(String.format("\n  福利待遇: %s", plan.getBenefitsDescription()));
        
        sb.append("\n\n时间信息:");
        sb.append(String.format("\n  开始日期: %s", plan.getStartDate()));
        sb.append(String.format("\n  结束日期: %s", plan.getEndDate()));
        sb.append(String.format("\n  发布日期: %s", plan.getPublishDate()));
        
        sb.append("\n\n其他信息:");
        sb.append(String.format("\n  面试流程: %s", plan.getInterviewProcess()));
        sb.append(String.format("\n  审批状态: %d", plan.getApproveStatus()));
        sb.append(String.format("\n  创建时间: %s", plan.getCreatedAt()));
        sb.append(String.format("\n  更新时间: %s", plan.getUpdatedAt()));
        
        if (plan.getContent() != null) {
            sb.append(String.format("\n\n计划内容:\n  %s", plan.getContent()));
        }
        
        sb.append("\n=================================================\n");
        
        log.info(sb.toString());
    }

    /**
     * 修改招聘公告
     * @param planDeptJob
     */
    @Override
    @Transactional
    public void updatePlanDeptJob(PlanDeptJob planDeptJob) {
        // 打印日志
        logUpdatePlanDeptJob(planDeptJob);
        
        // 执行更新操作
        Integer planType = recruitmentMapper.getPlanTypeByPlanId(planDeptJob.getPlanId());
        Integer r1 = 0;
        if (planType == 1) {
            r1 = recruitmentMapper.updatePlanDeptJob(planDeptJob);
        } else if (planType == 2) {
            r1 = recruitmentMapper.updatePlanAcademyJob(planDeptJob);
        }
        
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        Integer r2 = recruitmentMapper.updateRecruitmentPlan(planDeptJob.getPlanId(), LocalDateTime.now(), username);
        
        if (r1*r2 == 0) {
            log.error("更新失败: planType={}, planId={}", planType, planDeptJob.getPlanId());
            throw new RuntimeException("修改失败");
        }
        log.info("更新成功!");
    }

    /**
     * 修改其他招聘公告
     * @param planDeptJob
     */
    @Override
    @Transactional
    public void updateOtherPlan(PlanDeptJob planDeptJob) {
        log.info("\n==================== 更新其他招聘计划 ====================");
        log.info("计划ID: {}", planDeptJob.getPlanId());
        log.info("计划内容: {}", planDeptJob.getContent());
        log.info("=================================================\n");
        
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        Integer r1 = recruitmentMapper.updateOtherPlan(planDeptJob, LocalDateTime.now(), username);
        
        if (r1 == 0) {
            log.error("更新失败: planId={}", planDeptJob.getPlanId());
            throw new RuntimeException("修改失败");
        }
        log.info("更新成功!");
    }

    // 格式化日志(更新)
    private void logUpdatePlanDeptJob(PlanDeptJob planDeptJob) {
        StringBuilder sb = new StringBuilder();
        sb.append("\n==================== 更新招聘计划岗位 ====================\n");
        sb.append(String.format("基本信息:\n  计划ID: %d\n  部门编号: %s\n", 
            planDeptJob.getPlanId(), planDeptJob.getNumbering()));
        
        sb.append("\n岗位信息:");
        sb.append(String.format("\n  岗位编号: %s", planDeptJob.getPositionNumber()));
        sb.append(String.format("\n  岗位名称: %s", planDeptJob.getPositionName()));
        sb.append(String.format("\n  岗位属性: %s", planDeptJob.getPositionProperties()));
        sb.append(String.format("\n  岗位描述: %s", planDeptJob.getJobDescription()));
        sb.append(String.format("\n  岗位要求: %s", planDeptJob.getJobRequired()));
        sb.append(String.format("\n  招聘人数: %d", planDeptJob.getPerson()));
        
        sb.append("\n\n技能评分:");
        sb.append(String.format("\n  专业技能: %d", planDeptJob.getProfessionalSkillsRight()));
        sb.append(String.format("\n  沟通能力: %d", planDeptJob.getCommunicationSkillsRight()));
        sb.append(String.format("\n  团队协作: %d", planDeptJob.getTeamworkAbilityRight()));
        
        sb.append("\n=================================================\n");
        
        log.info(sb.toString());
    }

    /**
     * 删除招聘公告
     * @param planId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePlanDeptJob(Integer planId) {
        //先根据planId查询type
        Integer planType = recruitmentMapper.getPlanTypeByPlanId(planId);
        Integer r1 = recruitmentMapper.deleteRecruitmentPlanByPlanId(planId);
        Integer r2 = 0;
//        //校验
//        Recruitment recruitment = recruitmentMapper.getRecruitmentPlanByPlanId(planId);

        if (planType == 1) {
            r2 = recruitmentMapper.deletePlanDeptJobById(planId);
        } else if (planType == 2) {
            r2 = recruitmentMapper.deletePlanAcademyJobById(planId);
        }

        if (r1*r2 == 0) {
            try {
                throw new Exception("计划表删除失败");
            } catch (Exception e) {

            }
        }

    }

    


    /**
     * 下载文件
     */
    @Override
    public FileEntity getFile(Long planId) {
        return fileRepository.findById(planId)
                .orElseThrow(() -> new RuntimeException("文件不存在: " + planId));
    }

    /**
     * 检验部门ID和计划ID
     * @param newPostDTO
     * @return
     */
    @Override
    public String[] verify(NewPostDTO newPostDTO) {
        String[]  verifyRS = new String[2];
        verifyRS[0] = VerifyRS.NotPassed;
//检验计划ID
        Recruitment recruitment = recruitmentMapper.getRecruitmentPlanByPlanId(newPostDTO.getPlanId());
        if (recruitment == null){
            verifyRS[1] = "计划ID不存在";
            return verifyRS;
        }

        List<ALOfEDNDTO> depts = newPostDTO.getDepts();
//检验部门ID
        for (ALOfEDNDTO dept : depts) {
            Department department = departmentMapper.getDepartmentByDeptNumber(dept.getNumbering());
            if (department == null){
                verifyRS[1] = "部门ID不存在";
                return verifyRS;
            }
        }
//如果能走到这，说明通过校验
        verifyRS[0] = VerifyRS.Pass;


        return verifyRS;
    }

/**
 * 新增岗位
 */
    /*@Override
    @Transactional
    public void newPlanDeptJob(NewPostDTO newPostDTO) {
        Integer planId = newPostDTO.getPlanId();
        for (ALOfEDNDTO dept : newPostDTO.getDepts()) {
            String deptId = dept.getNumbering();
            for (PlanDeptJobDTO position : dept.getPositions()) {
                PlanDeptJob planDeptJob = PlanDeptJob.builder()
                        .planId(planId)
                        .numbering(deptId)
                        .positionName(position.getPositionName())
                        .jobDescription(position.getJobDescription())
                        .jobRequired(position.getJobRequired())
                        .person(position.getPerson())
                        .build();
                recruitmentMapper.newPlanDeptJob(planDeptJob);
            }
        }
    }*/

    /**
     *  根据所有主键删除岗位表
     * @param
     */
/*    @Override
    @Transactional
    public void deletePlanDeptJobByAllPrimaryKey(DeletePositionsRequest deletePositionsRequest) {
        List<PlanDeptJob> planDeptJobList = deletePositionsRequest.getDelPositions();
        for (PlanDeptJob planDeptJob : planDeptJobList) {
            recruitmentMapper.deletePlanDeptJobByAllPrimaryKey(planDeptJob);
        }

    }*/

    /**
     *  根据所有主键删除岗位表
     * @param
     */
    @Override
    public String[] verifyPlanDeptJobPrimaryKey(DeletePositionsRequest delPositons) {
        List<PlanDeptJob> planDeptJobList = delPositons.getDelPositions();

        String[]  verifyRS = new String[2];
        verifyRS[0] = VerifyRS.NotPassed;

        for (PlanDeptJob planDeptJob : planDeptJobList) {
            Integer planId = planDeptJob.getPlanId();
            String deptId = planDeptJob.getNumbering();
            String positionName = planDeptJob.getPositionName();

            //检验计划ID
            Recruitment recruitment = recruitmentMapper.getRecruitmentPlanByPlanId(planId);
            if (recruitment == null){
                verifyRS[1] = "计划ID不存在";
                return verifyRS;
            }

            //检验部门ID
            Department departmentToDeptNumber = departmentMapper.getDepartmentByDeptNumber(deptId);
            if (departmentToDeptNumber == null){
                verifyRS[1] = "部门ID不存在";
                return verifyRS;
            }
            //校验岗位名字
            List<PlanDeptJob> recruitmentToPositionName = recruitmentMapper.getDepartmentByPositionName(positionName);
            if (recruitmentToPositionName == null){
                verifyRS[1] = "岗位Name不存在";
                return verifyRS;
            }
        }
        verifyRS[0] = VerifyRS.Pass;

        return verifyRS;
    }

    /**
     * 新增岗位
     * @param planType 计划类型（1：管理岗位、2：二级学院岗位）
     * @param planId 招聘计划ID
     * @param alOfEDNDTOS 部门/学院及其岗位集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPost(Integer planType, Integer planId, List<ALOfEDNDTO> alOfEDNDTOS) {
        try {
            // 遍历每个部门/二级学院
            for (ALOfEDNDTO dept : alOfEDNDTOS) {
                List<PlanDeptJobDTO> positions = dept.getPositions();
                // 遍历每个岗位
                for (PlanDeptJobDTO position : positions) {
                    PlanDeptJob planDeptJob = PlanDeptJob.builder()
                            .planId(planId)
                            .numbering(dept.getNumbering())
                            .positionNumber(position.getPositionNumber())
                            .positionName(position.getPositionName())
                            .positionProperties(position.getPositionProperties())
                            .jobDescription(position.getJobDescription())
                            .jobRequired(position.getJobRequired())
                            .person(position.getPerson())
                            .professionalSkillsRight(position.getProfessionalSkillsRight())
                            .communicationSkillsRight(position.getCommunicationSkillsRight())
                            .teamworkAbilityRight(position.getTeamworkAbilityRight())
                            .build();
                    // 根据 planType 插入不同的招聘公告表
                    if (planType == 1) {
                        recruitmentMapper.newPlanDeptJob(planDeptJob);
                    } else if (planType == 2) {
                        recruitmentMapper.newPlanAcademyJob(planDeptJob);
                    }
                }
            }
        } catch (org.springframework.dao.DataIntegrityViolationException ex) {
            // 提取异常中更详细的信息
            String detailedMessage = ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage();
            // 组装详细错误提示
            throw new RuntimeException("添加用人部门岗位失败，可能存在重复条目，错误详情：" + detailedMessage, ex);
        } catch (Exception e) {
            throw new RuntimeException("添加用人部门岗位失败，原因：" + e.getMessage(), e);
        }
    }

    /**
     * 删除岗位
     * @param deletePositions
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePost(DeletePositions deletePositions) {
        for (DelPositions delPosition : deletePositions.getDelPositions()) {
            //先根据planId查询type
            Integer planType = recruitmentMapper.getPlanTypeByPlanId(delPosition.getPlanId());
            System.out.println(planType);
            if (planType == 1) {
                recruitmentMapper.deletePlanDeptJobByAllPrimaryKey(delPosition);
            } else if (planType == 2) {
                recruitmentMapper.deletePlanAcademyJobByAllPrimaryKey(delPosition);
            }
        }
    }

    @Override
    public Integer verifyAddCondition(RecruitmentDTO recruitmentDTO) {

        for (ALOfEDNDTO dept : recruitmentDTO.getDepts()) {
            if (recruitmentDTO.getPlanType() == 1) {
                Department departmentNumber = departmentMapper.getDepartmentByDeptNumber(dept.getNumbering());
                if (departmentNumber ==null) {
                    return 2;
                }
            } else if (recruitmentDTO.getPlanType() == 2) {
                Academy academyNumber = academyMapper.getAcademyByDeptNumber(dept.getNumbering());

                if (academyNumber == null) {
                    return 2;
                }
            }

            for (PlanDeptJobDTO position : dept.getPositions()){
                if (departmentMapper.getPositionByDeptNumber(position.getPositionNumber()) == null) {
                    return 3;
                }
            }
        }

        return 1;
    }

}
